30 changed files with 2009 additions and 48 deletions
@ -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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
<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 @@ |
|||||||
|
// 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 @@ |
|||||||
<UserControl x:Class="ICSharpCode.CodeQuality.Gui.MainView" |
<UserControl x:Class="ICSharpCode.CodeQuality.Gui.MainView" |
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
xmlns:gui="clr-namespace:ICSharpCode.CodeQuality.Gui" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||||
<DockPanel> |
<DockPanel> |
||||||
<ToolBar DockPanel.Dock="Top"> |
<ToolBar DockPanel.Dock="Top"> |
||||||
<Button>Add Assembly</Button> |
<Button Click="AddAssemblyClick">Add Assembly</Button> |
||||||
</ToolBar> |
</ToolBar> |
||||||
<TabControl> |
<TabControl> |
||||||
<TabItem Header="Dependency Matrix"> |
<TabItem Header="Dependency Matrix"> |
||||||
|
<gui:DependencyMatrixView x:Name="matrix" /> |
||||||
</TabItem> |
</TabItem> |
||||||
</TabControl> |
</TabControl> |
||||||
</DockPanel> |
</DockPanel> |
||||||
|
|||||||
@ -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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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 @@ |
|||||||
|
// 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