///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Collections;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using JetBrains.UI.Components.CustomListView;
using JetBrains.UI.RichText;
namespace JetBrains.UI.Components.RichTextListView
{
///
/// Enumerates possible alignments for columns
///
public enum ColumnAlignment
{
Left,
Right,
Center
}
///
/// Paints items in columns
///
public class ColumnItemPainter : Components.CustomListView.IItemPainter
{
///
/// Sets spacing between columns
///
private const int SPACING = 10;
///
/// Stores alignments for columns
///
private ColumnAlignment[] myAlignments;
///
/// The painters to use for rendering
///
private IItemPainter[] myPainters;
///
/// The starting offsets
///
private int[] myOffsets;
///
/// Indicates wheter the starting offsets are correct
///
private bool myOffsetsAreCorrect;
///
/// List of registered items
///
private ArrayList myItems = new ArrayList();
///
/// The width
///
private int myWidth;
public int Width
{
get { return myWidth; }
}
public ColumnItemPainter( ColumnAlignment[] alignments, IItemPainter[] painters )
{
myAlignments = alignments;
myPainters = painters;
myOffsetsAreCorrect = false;
}
public void RegisterItem( ListViewItem item )
{
if (!IsHandled(item))
throw new ArgumentException("The item is not handled by at least one item painter. Please register the item in all item painters first");
myItems.Add(item);
myOffsetsAreCorrect = false;
}
#region IItemPainter Members
public bool IsHandled(ListViewItem item)
{
foreach (IItemPainter painter in myPainters)
if (!painter.IsHandled(item))
return false;
return true;
}
public Size GetSize(ListViewItem item, Graphics g)
{
if (!myOffsetsAreCorrect)
UpdateOffsets(g);
int maxHeight = 0;
foreach (IItemPainter painter in myPainters)
{
int height = painter.GetSize(item, g).Height;
if (height > maxHeight)
maxHeight = height;
}
return new Size(myWidth, maxHeight);
}
public void Draw(ListViewItem item, Graphics g, Rectangle rect)
{
if (!myOffsetsAreCorrect)
UpdateOffsets(g);
int startOffset = CalculateOffset(item);
for (int i = 0; i < myPainters.Length; i++)
{
IItemPainter painter = myPainters[i];
Size size = painter.GetSize(item, g);
int offset = myOffsets[i] + startOffset;
int endOffset = i == myPainters.Length - 1 ? rect.Width : myOffsets[i + 1];
switch (myAlignments[i])
{
case ColumnAlignment.Right:
offset += (endOffset - offset) - size.Width;
break;
case ColumnAlignment.Center:
offset += ((endOffset - offset) - size.Width) / 2;
break;
}
painter.Draw(item, g, new Rectangle(offset, 0, endOffset - offset, 0));
}
}
public ListViewItem GetItemAt(ListView ListView, Point point)
{
return null;
}
#endregion
#region Private methods
private void UpdateOffsets( Graphics g )
{
myOffsets = new int[myPainters.Length];
int offset = 0;
for (int i = 0; i < myPainters.Length; i++)
{
IItemPainter painter = myPainters[i];
myOffsets[i] = offset;
int maxWidth = 0;
foreach (ListViewItem item in myItems)
{
Size size = painter.GetSize(item, g);
if (size.Width > maxWidth)
maxWidth = size.Width;
}
offset += maxWidth + SPACING;
}
myWidth = offset;
myOffsetsAreCorrect = true;
}
///
/// Calculates offset of a given Item from the left border
///
private int CalculateOffset( ListViewItem item )
{
int offset = 0;
//if ( item.ImageList != null && item.ImageList.Images.Count > 0 && item.ImageIndex >= 0 )
offset += 17;
if ( item.ListView.CheckBoxes )
offset += 17;
return offset;
}
#endregion
}
}