/// /// 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 } }