Browse Source

MatrixControl now implements IScrollInfo and supports UI virtualization.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6428 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
pull/1/head
Tomáš Linhart 15 years ago
parent
commit
89ffbd64b7
  1. 16
      src/AddIns/Analysis/CodeQuality/CodeQualityAnalysis.csproj
  2. 312
      src/AddIns/Analysis/CodeQuality/Src/Controls/MatrixControl.cs
  3. 13
      src/AddIns/Analysis/CodeQuality/Src/Controls/TreeMatrixControl.xaml

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

@ -113,16 +113,12 @@
<Compile Include="Src\Controls\DependencyEdge.cs" /> <Compile Include="Src\Controls\DependencyEdge.cs" />
<Compile Include="Src\Controls\DependencyGraph.cs" /> <Compile Include="Src\Controls\DependencyGraph.cs" />
<Compile Include="Src\Controls\DependencyGraphLayout.cs" /> <Compile Include="Src\Controls\DependencyGraphLayout.cs" />
<Compile Include="Src\Controls\DependencyMatrixControl.cs"> <Compile Include="Src\Controls\DependencyMatrixControl.cs" />
<SubType>Component</SubType>
</Compile>
<Compile Include="Src\Controls\DependencyMatrix.cs" /> <Compile Include="Src\Controls\DependencyMatrix.cs" />
<Compile Include="Src\Controls\DependencyVertex.cs" /> <Compile Include="Src\Controls\DependencyVertex.cs" />
<Compile Include="Src\Controls\DependencyIconVertexConverter.cs" /> <Compile Include="Src\Controls\DependencyIconVertexConverter.cs" />
<Compile Include="Src\Controls\Matrix.cs" /> <Compile Include="Src\Controls\Matrix.cs" />
<Compile Include="Src\Controls\MatrixControl.cs"> <Compile Include="Src\Controls\MatrixControl.cs" />
<SubType>Component</SubType>
</Compile>
<Compile Include="Src\Controls\TreeMatrixControl.xaml.cs"> <Compile Include="Src\Controls\TreeMatrixControl.xaml.cs">
<DependentUpon>TreeMatrixControl.xaml</DependentUpon> <DependentUpon>TreeMatrixControl.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
@ -220,12 +216,12 @@
<ProjectReference Include="..\..\..\Main\ICSharpCode.Core.Presentation\ICSharpCode.Core.Presentation.csproj"> <ProjectReference Include="..\..\..\Main\ICSharpCode.Core.Presentation\ICSharpCode.Core.Presentation.csproj">
<Project>{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}</Project> <Project>{7E4A7172-7FF5-48D0-B719-7CD959DD1AC9}</Project>
<Name>ICSharpCode.Core.Presentation</Name> <Name>ICSharpCode.Core.Presentation</Name>
<Private>False</Private> <Private>True</Private>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\..\Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj"> <ProjectReference Include="..\..\..\Main\ICSharpCode.SharpDevelop.Widgets\Project\ICSharpCode.SharpDevelop.Widgets.csproj">
<Project>{8035765F-D51F-4A0C-A746-2FD100E19419}</Project> <Project>{8035765F-D51F-4A0C-A746-2FD100E19419}</Project>
<Name>ICSharpCode.SharpDevelop.Widgets</Name> <Name>ICSharpCode.SharpDevelop.Widgets</Name>
<Private>False</Private> <Private>True</Private>
<EmbedInteropTypes>False</EmbedInteropTypes> <EmbedInteropTypes>False</EmbedInteropTypes>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\DisplayBindings\WpfDesign\WpfDesign.Designer\Project\WpfDesign.Designer.csproj"> <ProjectReference Include="..\..\DisplayBindings\WpfDesign\WpfDesign.Designer\Project\WpfDesign.Designer.csproj">
@ -240,9 +236,7 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup />
<Folder Include="Themes" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

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

@ -1,27 +1,43 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using System.Windows.Threading;
namespace ICSharpCode.CodeQualityAnalysis.Controls namespace ICSharpCode.CodeQualityAnalysis.Controls
{ {
public class MatrixControl<TValue> : FrameworkElement // TODO: Virtualization public class MatrixControl<TValue> : FrameworkElement, IScrollInfo
{ {
Dictionary<string, ImageSource> imgs = new Dictionary<string, ImageSource>(); private Dictionary<string, ImageSource> imgs = new Dictionary<string, ImageSource>();
Point currentPoint = new Point(-1, -1); private Coords currentCell = new Coords(-1, -1);
string font; 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 // will be loaded from Matrix
int cellsVertically = 25; private int matrixWidth = 0;
int cellsHorizontally = 25; private int matrixHeight = 0;
private Matrix<TValue> matrix;
public Matrix<TValue> Matrix { get; set; } public Matrix<TValue> Matrix
{
get { return matrix; }
set
{
matrix = value;
matrixHeight = Matrix.HeaderRows.Count;
matrixWidth = Matrix.HeaderColumns.Count;
}
}
public int CellHeight { get; set; } public int CellHeight { get; set; }
@ -30,6 +46,8 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
public MatrixControl() public MatrixControl()
{ {
CellHeight = CellWidth = 36; CellHeight = CellWidth = 36;
matrixWidth = 20;
matrixHeight = 20;
font = "Verdana"; font = "Verdana";
} }
@ -38,10 +56,12 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
base.OnMouseMove(e); base.OnMouseMove(e);
var point = e.GetPosition(this); var point = e.GetPosition(this);
if (point.X < cellsHorizontally * CellWidth && point.Y < cellsVertically * CellHeight) if (point.X < matrixWidth * CellWidth && point.Y < matrixHeight * CellHeight)
currentPoint = point; currentCell = new Coords(
(int)((point.X + offset.X) / CellWidth),
(int)((point.Y + offset.Y) / CellHeight));
else else
currentPoint = new Point(-1, -1); currentCell = new Coords(-1, -1);
InvalidateVisual(); InvalidateVisual();
} }
@ -49,15 +69,36 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
protected override void OnRender(DrawingContext drawingContext) protected override void OnRender(DrawingContext drawingContext)
{ {
base.OnRender(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
var cellsHorizontally = maxWidth > matrixWidth ? matrixWidth : maxWidth;
var cellsVertically = maxHeight > matrixHeight ? matrixHeight : maxHeight;
// number of cell which will be drawn
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 // background
var background = new Rect(0, 0, cellsHorizontally * CellWidth, cellsVertically * CellHeight); var background = new Rect(0, 0, cellsHorizontally * CellWidth, cellsVertically * CellHeight);
var backgroundColor = new SolidColorBrush(Colors.Yellow); var backgroundColor = new SolidColorBrush(Colors.Yellow);
drawingContext.DrawRectangle(backgroundColor, null, background); drawingContext.DrawRectangle(backgroundColor, null, background);
// hover cell // hover cell
if (currentPoint.X > 0 || currentPoint.Y > 0) { if (currentCell.X >= 0 || currentCell.Y >= 0) {
var rect = new Rect(currentPoint.X - currentPoint.X % CellWidth, currentPoint.Y - currentPoint.Y % CellHeight, CellWidth, CellHeight); var rect = new Rect(
(currentCell.X - scaledOffsetX) * CellWidth - offsetDiffX,
(currentCell.Y - scaledOffsetY) * CellHeight - offsetDiffY,
CellWidth,
CellHeight);
var brush = new SolidColorBrush(Colors.Red); var brush = new SolidColorBrush(Colors.Red);
drawingContext.DrawRectangle(brush, null, rect); drawingContext.DrawRectangle(brush, null, rect);
} }
@ -65,33 +106,37 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
// grid // grid
var pen = new Pen(Brushes.Black, 1); var pen = new Pen(Brushes.Black, 1);
for (int i = 0; i <= cellsHorizontally; i++) { // grid x
for (int i = 0; i <= cellsHorizontally; i++)
drawingContext.DrawLine(pen, drawingContext.DrawLine(pen,
new Point(i * CellWidth, 0), new Point(i * CellWidth - offsetDiffX, 0),
new Point(i * CellWidth, new Point(i * CellWidth - offsetDiffX,
cellsHorizontally * CellWidth)); cellsVertically * CellWidth));
} // grid y
for (int i = 0; i <= cellsVertically; i++)
for (int i = 0; i <= cellsVertically; i++) {
drawingContext.DrawLine(pen, drawingContext.DrawLine(pen,
new Point(0, i * CellHeight), new Point(0, i * CellHeight - offsetDiffY),
new Point(cellsVertically * CellHeight, new Point(cellsHorizontally * CellHeight,
i * 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 // text
for (int i = 0; i < cellsHorizontally; i++) { for (int i = 0; i < cellsHorizontally; i++)
for (int j = 0; j < cellsVertically; j++) { for (int j = 0; j < cellsVertically; j++)
drawingContext.DrawImage(CreateText(i * j), new Rect(i * CellWidth, j * CellHeight, CellWidth, CellHeight)); drawingContext.DrawImage(
} CreateText((i + scaledOffsetX) * (j + scaledOffsetY)),
} new Rect(i * CellWidth - offsetDiffX, j * CellHeight - offsetDiffY, CellWidth, CellHeight));
} }
public ImageSource CreateText(int number) public ImageSource CreateText(int number)
{ {
return CreateText(number.ToString()); return CreateText(number.ToString());
} }
public ImageSource CreateText(string text) public ImageSource CreateText(string text)
{ {
if (imgs.ContainsKey(text)) if (imgs.ContainsKey(text))
@ -106,19 +151,206 @@ namespace ICSharpCode.CodeQualityAnalysis.Controls
var size = g.MeasureString(text, fontOjb); var size = g.MeasureString(text, fontOjb);
float spanWidth = CellWidth / 2 - size.Width / 2; var spanWidth = (CellWidth - size.Width) / 2;
float spanHeight = CellHeight / 2 - size.Height / 2; var spanHeight = (CellHeight - size.Height) / 2;
g.DrawString(text, fontOjb, System.Drawing.Brushes.Black, new System.Drawing.PointF(spanWidth, spanHeight)); g.DrawString(text, fontOjb, System.Drawing.Brushes.Black, new System.Drawing.PointF(spanWidth, spanHeight));
g.Dispose(); g.Dispose();
var img = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), var img = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(),
IntPtr.Zero, IntPtr.Zero,
System.Windows.Int32Rect.Empty, Int32Rect.Empty,
BitmapSizeOptions.FromWidthAndHeight(bmp.Width, bmp.Height)); BitmapSizeOptions.FromWidthAndHeight(bmp.Width, bmp.Height));
imgs.Add(text, img); imgs.Add(text, img);
return img; 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 - 1);
}
public void LineDown()
{
SetVerticalOffset(VerticalOffset + 1);
}
public void LineLeft()
{
SetHorizontalOffset(HorizontalOffset - 1);
}
public void LineRight()
{
SetHorizontalOffset(HorizontalOffset + 1);
}
public void PageUp()
{
SetVerticalOffset(VerticalOffset - CellHeight);
}
public void PageDown()
{
SetVerticalOffset(VerticalOffset + CellHeight);
}
public void PageLeft()
{
SetHorizontalOffset(HorizontalOffset - CellWidth);
}
public void PageRight()
{
SetHorizontalOffset(HorizontalOffset + CellWidth);
}
public void MouseWheelUp()
{
SetVerticalOffset(VerticalOffset - 4);
}
public void MouseWheelDown()
{
SetVerticalOffset(VerticalOffset + 4);
}
public void MouseWheelLeft()
{
SetVerticalOffset(HorizontalOffset + 4);
}
public void MouseWheelRight()
{
SetVerticalOffset(HorizontalOffset + 4);
}
public void SetHorizontalOffset(double offset)
{
if (offset == this.offset.X) return;
this.offset.X = offset;
InvalidateVisual();
}
public void SetVerticalOffset(double offset)
{
if (offset == this.offset.Y) return;
this.offset.Y = offset;
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));
ScrollOwner.InvalidateScrollInfo();
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;
}
}
} }
} }

13
src/AddIns/Analysis/CodeQuality/Src/Controls/TreeMatrixControl.xaml

@ -11,12 +11,12 @@
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TreeView Name="leftTree" Grid.Row="1" Grid.Column="0"> <TreeView Name="leftTree" Grid.Row="1" Grid.Column="0">
@ -31,11 +31,8 @@
</TreeView.LayoutTransform> </TreeView.LayoutTransform>
</TreeView> </TreeView>
<Controls:DependencyMatrixControl Grid.Column="1" Grid.Row="1" <ScrollViewer Grid.Column="1" Grid.Row="1" CanContentScroll="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
x:Name="matrixControl" <Controls:DependencyMatrixControl x:Name="matrixControl" />
HorizontalAlignment="Stretch" </ScrollViewer>
VerticalAlignment="Stretch">
</Controls:DependencyMatrixControl>
</Grid> </Grid>
</UserControl> </UserControl>
Loading…
Cancel
Save