Browse Source

Improvements to Matrix Control.

pull/19/head
Tomas Linhart 14 years ago
parent
commit
6061837e06
  1. 2
      src/AddIns/Analysis/CodeQuality/CodeQualityAnalysis.csproj
  2. 68
      src/AddIns/Analysis/CodeQuality/Src/Controls/DependencyColorizer.cs
  3. 11
      src/AddIns/Analysis/CodeQuality/Src/Controls/DependencyMatrix.cs
  4. 93
      src/AddIns/Analysis/CodeQuality/Src/Controls/MatrixControl.cs
  5. 3
      src/AddIns/Analysis/CodeQuality/Src/Controls/TreeMatrixControl.xaml.cs
  6. 35
      src/AddIns/Analysis/CodeQuality/Src/Helper.cs
  7. 2
      src/AddIns/Analysis/CodeQuality/Src/Relationship.cs
  8. 70
      src/AddIns/Analysis/CodeQuality/Src/Type.cs
  9. 18
      src/AddIns/Analysis/CodeQuality/Src/Utility/IColorizer.cs
  10. 4
      src/AddIns/Analysis/CodeQuality/Src/Utility/Matrix.cs

2
src/AddIns/Analysis/CodeQuality/CodeQualityAnalysis.csproj

@ -113,6 +113,7 @@ @@ -113,6 +113,7 @@
<Compile Include="..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Src\Controls\DependencyColorizer.cs" />
<Compile Include="Src\Controls\DependencyEdge.cs" />
<Compile Include="Src\Controls\DependencyGraph.cs" />
<Compile Include="Src\Controls\DependencyGraphLayout.cs" />
@ -143,6 +144,7 @@ @@ -143,6 +144,7 @@
<Compile Include="Src\RelationshipType.cs" />
<Compile Include="Src\Type.cs" />
<Compile Include="Src\Utility\DoubleKeyDictionary.cs" />
<Compile Include="Src\Utility\IColorizer.cs" />
<Compile Include="Src\Utility\Matrix.cs" />
<Compile Include="Src\Utility\RelayCommand.cs" />
<Compile Include="Src\Utility\ViewModelBase.cs" />

68
src/AddIns/Analysis/CodeQuality/Src/Controls/DependencyColorizer.cs

@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
// 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.Linq;
using System.Collections.Generic;
using System.Windows.Media;
using ICSharpCode.CodeQualityAnalysis.Utility;
namespace ICSharpCode.CodeQualityAnalysis.Controls
{
/// <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.Relationships.Any(r => r == RelationshipType.UseThis))
return Colors.Azure;
if (relationship.Relationships.Any(r => r == RelationshipType.UsedBy))
return Colors.Beige;
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;
}
}
}

11
src/AddIns/Analysis/CodeQuality/Src/Controls/DependencyMatrix.cs

@ -13,7 +13,16 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -13,7 +13,16 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
{
protected override Relationship GetCellValue(int rowIndex, int columnIndex)
{
return HeaderRows[rowIndex].Value.GetRelationship(HeaderColumns[columnIndex].Value);
var toRelationship = HeaderRows[rowIndex].Value.GetRelationship(HeaderColumns[columnIndex].Value);
var fromRelationship = HeaderColumns[columnIndex].Value.GetRelationship(HeaderRows[rowIndex].Value);
// add other way
foreach (var relationship in fromRelationship.Relationships) {
if (relationship == RelationshipType.UseThis)
toRelationship.AddRelationship(RelationshipType.UsedBy);
}
return toRelationship;
}
}
}

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

@ -32,6 +32,9 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -32,6 +32,9 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
private int matrixWidth = 0;
private int matrixHeight = 0;
private int fontSize = 0;
private int penSize = 0;
private Matrix<TItem, TValue> matrix;
public Matrix<TItem, TValue> Matrix
@ -54,11 +57,15 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -54,11 +57,15 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
public bool RenderZeroes { get; set; }
public IColorizer<TValue> Colorizer { get; set; }
public MatrixControl()
{
CellHeight = CellWidth = 36;
CellHeight = CellWidth = 18;
matrixWidth = 20;
matrixHeight = 20;
fontSize = CellHeight / 3;
penSize = 1;
font = "Verdana";
HoveredCell = new HoveredCell<TValue>();
@ -69,12 +76,13 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -69,12 +76,13 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
base.OnMouseMove(e);
var point = e.GetPosition(this);
if (point.X < matrixWidth * CellWidth && point.Y < matrixHeight * CellHeight)
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
currentCell = new Coords(-1, -1);
// 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)
@ -112,27 +120,38 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -112,27 +120,38 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
// background
var background = new Rect(0, 0, cellsHorizontally * CellWidth, cellsVertically * CellHeight);
var backgroundColor = new SolidColorBrush(Colors.Yellow);
backgroundColor.Freeze();
drawingContext.DrawRectangle(backgroundColor, null, background);
// sometimes happens when half of cell is hidden in scroll so text isnt drawn
// so lets drawn one more cell
cellsHorizontally = maxWidth > matrixWidth ? matrixWidth : maxWidth + 1;
cellsVertically = maxHeight > matrixHeight ? matrixHeight : maxHeight + 1;
var currentXLine = (currentCell.X - scaledOffsetX) * CellWidth - offsetDiffX;
var currentYLine = (currentCell.Y - scaledOffsetY) * CellHeight - offsetDiffY;
// hovering
if (currentCell.X >= 0 || currentCell.Y >= 0) {
// hover x line
// hover y line
var rect = new Rect(0,
(currentCell.Y - scaledOffsetY) * CellHeight - offsetDiffY,
currentYLine,
CellWidth * cellsHorizontally,
CellHeight);
var brush = new SolidColorBrush(Colors.GreenYellow);
brush.Freeze();
drawingContext.DrawRectangle(brush, null, rect);
// hover y line
rect = new Rect((currentCell.X - scaledOffsetX) * CellWidth - offsetDiffX,
// 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
@ -143,11 +162,44 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -143,11 +162,44 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
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 = i + scaledOffsetX;
int columnIndex = j + scaledOffsetY;
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 ||
((i * CellWidth - offsetDiffX) == currentXLine))
brush = Colorizer.GetColorBrushMixedWith(Colors.GreenYellow, value);
else
brush = Colorizer.GetColorBrush(value);
drawingContext.DrawRectangle(brush, null, rect);
}
if (!RenderZeroes && 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, 1);
var pen = new Pen(Brushes.Black, penSize);
pen.Freeze();
// grid x
for (int i = 0; i <= cellsHorizontally; i++)
@ -161,30 +213,10 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -161,30 +213,10 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
new Point(0, i * CellHeight - offsetDiffY),
new Point(cellsHorizontally * CellHeight,
i * CellHeight - offsetDiffY));
// sometimes happens when half of cell is hidden in scroll so text isnt drawn
// so lets drawn one more cell
cellsHorizontally = maxWidth > matrixWidth ? matrixWidth : maxWidth + 1;
cellsVertically = maxHeight > matrixHeight ? matrixHeight : maxHeight + 1;
// text
for (int i = 0; i < cellsHorizontally; i++) {
for (int j = 0; j < cellsVertically; j++) {
int rowIndex = i + scaledOffsetX;
int columnIndex = j + scaledOffsetY;
var value = matrix[rowIndex, columnIndex];
drawingContext.DrawImage(
CreateText(value.Text),
new Rect(i * CellWidth - offsetDiffX, j * CellHeight - offsetDiffY, CellWidth, CellHeight));
}
}
}
public ImageSource CreateText(string text)
{
if (!RenderZeroes && text == "0") // rendering zeroes would be distracting
text = string.Empty;
if (imgs.ContainsKey(text))
return imgs[text];
@ -193,7 +225,7 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -193,7 +225,7 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
g.SmoothingMode = SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
var fontOjb = new System.Drawing.Font(font, 12);
var fontOjb = new System.Drawing.Font(font, fontSize);
var size = g.MeasureString(text, fontOjb);
@ -207,6 +239,7 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -207,6 +239,7 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromWidthAndHeight(bmp.Width, bmp.Height));
img.Freeze();
imgs.Add(text, img);
return img;

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

@ -38,8 +38,9 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls @@ -38,8 +38,9 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
public TreeMatrixControl()
{
InitializeComponent();
}
matrixControl.Colorizer = new DependencyColorizer();
}
public void DrawTree(Module module)
{

35
src/AddIns/Analysis/CodeQuality/Src/Helper.cs

@ -1,25 +1,21 @@ @@ -1,25 +1,21 @@
/*
* Created by SharpDevelop.
* User: Peter Forstmeier
* Date: 02.09.2011
* Time: 23:10
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
// 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.Windows.Media;
namespace ICSharpCode.CodeQualityAnalysis
{
/// <summary>
/// Description of Helper.
/// </summary>
public class Helper
public static class Helper
{
public static void FillTree(ICSharpCode.TreeView.SharpTreeView tree,Module module)
{
tree.ShowRoot = false;
var root = CreateTreeItem(module);
tree.Root = root;
tree.ShowRoot = false;
foreach (var ns in module.Namespaces)
{
@ -34,23 +30,36 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -34,23 +30,36 @@ namespace ICSharpCode.CodeQualityAnalysis
foreach (var method in type.Methods)
{
var methodName = CreateTreeItem(method);
namespaceNode.Children.Add(methodName);
typeNode.Children.Add(methodName);
}
foreach (var field in type.Fields)
{
var fieldNode = CreateTreeItem(field);
namespaceNode.Children.Add(fieldNode);
typeNode.Children.Add(fieldNode);
}
}
}
}
private static DependecyTreeNode CreateTreeItem (INode node)
{
DependecyTreeNode dtn = new DependecyTreeNode(node);
return dtn;
}
public static Color MixedWith(this Color c1, Color c2)
{
int r = Math.Min((c1.R + c2.R), 255);
int g = Math.Min((c1.G + c2.G), 255);
int b = Math.Min((c1.B + c2.B), 255);
return new Color
{
R = Convert.ToByte(r),
G = Convert.ToByte(g),
B = Convert.ToByte(b)
};
}
}
}

2
src/AddIns/Analysis/CodeQuality/Src/Relationship.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -25,7 +25,7 @@ namespace ICSharpCode.CodeQualityAnalysis
public void AddRelationship(RelationshipType type)
{
if (type == RelationshipType.UseThis)
if (type == RelationshipType.UseThis || type == RelationshipType.UsedBy)
OccurrenceCount++;
Relationships.Add(type);

70
src/AddIns/Analysis/CodeQuality/Src/Type.cs

@ -255,13 +255,71 @@ namespace ICSharpCode.CodeQualityAnalysis @@ -255,13 +255,71 @@ namespace ICSharpCode.CodeQualityAnalysis
public Relationship GetRelationship(INode node)
{
// if (node is Namespace) {
// Namespace ns = (Namespace)node;
// if (ns.Types.Contains(this)
// return RelationshipType.Contains;
// }
Relationship relationship = new Relationship();
return new Relationship();
if (node == this) {
relationship.Relationships.Add(RelationshipType.Same);
return relationship;
}
if (node is Namespace) {
Namespace ns = (Namespace)node;
if (this.Namespace.Name == ns.Name) {
relationship.AddRelationship(RelationshipType.UseThis);
}
if (this.BaseType != null && this.BaseType.Namespace.Name == ns.Name) {
relationship.AddRelationship(RelationshipType.UseThis);
}
foreach (var type in this.GenericBaseTypes) {
if (type.Namespace.Name == ns.Name) {
relationship.AddRelationship(RelationshipType.UseThis);
}
}
foreach (var type in this.GenericImplementedInterfacesTypes) {
if (type.Namespace.Name == ns.Name) {
relationship.AddRelationship(RelationshipType.UseThis);
}
}
foreach (var type in this.ImplementedInterfaces) {
if (type.Namespace.Name == ns.Name) {
relationship.AddRelationship(RelationshipType.UseThis);
}
}
foreach (var field in this.Fields) {
if (field.DeclaringType.Namespace.Name == ns.Name) {
relationship.AddRelationship(RelationshipType.UseThis);
}
if (field.FieldType != null && field.FieldType.Namespace.Name == ns.Name) {
relationship.AddRelationship(RelationshipType.UseThis);
}
if (field.GenericTypes.Any(type => type.Namespace.Name == ns.Name)) {
relationship.AddRelationship(RelationshipType.UseThis);
}
}
foreach (var method in this.Methods) {
if (method.TypeUses.Any(type => type.Namespace.Name == ns.Name)) {
relationship.AddRelationship(RelationshipType.UseThis);
}
if (method.GenericReturnTypes.Any(type => type.Namespace.Name == ns.Name)) {
relationship.AddRelationship(RelationshipType.UseThis);
}
if (method.DeclaringType != null && method.DeclaringType.Namespace.Name == ns.Name) {
relationship.AddRelationship(RelationshipType.UseThis);
}
if (method.ReturnType != null && method.ReturnType.Namespace.Name == ns.Name) {
relationship.AddRelationship(RelationshipType.UseThis);
}
}
}
return relationship;
}
public override string ToString()

18
src/AddIns/Analysis/CodeQuality/Src/Utility/IColorizer.cs

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
// 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.Windows.Media;
namespace ICSharpCode.CodeQualityAnalysis.Utility
{
/// <summary>
/// Description of IColorizer.
/// </summary>
public interface IColorizer<TValue>
{
SolidColorBrush GetColorBrush(TValue value);
SolidColorBrush GetColorBrushMixedWith(Color color, TValue value);
Color GetColor(TValue value);
}
}

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

@ -36,6 +36,10 @@ namespace ICSharpCode.CodeQualityAnalysis.Utility @@ -36,6 +36,10 @@ namespace ICSharpCode.CodeQualityAnalysis.Utility
{
get
{
if (rowIndex > HeaderRows.Count || rowIndex < 0 ||
columnIndex > HeaderColumns.Count || columnIndex < 0)
return default(TValue);
var cacheResult = GetFromCache(rowIndex, columnIndex);
if (cacheResult != null)
return cacheResult;

Loading…
Cancel
Save