/// /// 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.RichText; namespace JetBrains.UI.Components.RichTextListView { /// /// Paints Items using rich text /// public class RichTextItemPainter : Components.CustomListView.IItemPainter { /// /// List of handled Items /// private Hashtable myItems = new Hashtable(); /// /// Adds text to a List Item /// public void Add( ListViewItem item, RichText.RichText text ) { myItems[item] = text; //InvalidateItem(Item); } /// /// Removes a Item /// public void Remove( ListViewItem item ) { myItems.Remove(item); } /// /// Gets rich text by a List Item /// public RichText.RichText this[ ListViewItem item ] { get { return (RichText.RichText)myItems[item]; } set { myItems[item] = value; } } // removes all items public void Clear() { myItems = new Hashtable(myItems.Count); } #region IItemPainter Members public bool IsHandled(System.Windows.Forms.ListViewItem item) { return myItems.Contains(item); } public Size GetSize( ListViewItem item, Graphics g ) { if (!IsHandled(item)) return new Size(); RichText.RichText text = (RichText.RichText)myItems[item]; IntPtr hdc = g.GetHdc(); try { Size size = text.GetSize(hdc).ToSize(); size.Height = item.Bounds.Height; size.Width += 3 + CalculateOffset(item); return size; } finally { g.ReleaseHdc( hdc ); } } public void Draw(System.Windows.Forms.ListViewItem item, System.Drawing.Graphics g, Rectangle boundRect) { if (!IsHandled(item)) return; ListView listView = item.ListView; RichText.RichText text = (RichText.RichText)myItems[item]; Rectangle rect = CalculateItemRectangle(item, boundRect); Rectangle contentRect = CalculateContentRectangle(item, g, rect); // Center content vertically if (contentRect.Height < rect.Height) { int topOffset = (rect.Height - contentRect.Height) / 2; contentRect.Y += topOffset; } g.FillRectangle(new SolidBrush(listView.BackColor), rect); if ( item.Selected ) { Color backgroundColor = Colors.ListSelectionBackColor(listView.Focused); text = (RichText.RichText)text.Clone(); g.FillRectangle(new SolidBrush(backgroundColor), rect); text.SetColors(SystemColors.HighlightText, backgroundColor); } g.SetClip(rect); IntPtr hdc = g.GetHdc(); try { text.Draw(hdc, contentRect); } finally { g.ReleaseHdc( hdc ); } if ( item.Selected && listView.Focused ) DrawDottedRectangle(g, rect); } public ListViewItem GetItemAt( ListView listView, Point point ) { return listView.GetItemAt(point.X,point.Y); } // public void InvalidateItem( ListViewItem item ) // { // Rectangle rect = new Rectangle(item.Bounds.Location, new Size(item.ListView.ClientSize.Width, item.Bounds.Height)); // item.ListView.Invalidate( rect ); // } #endregion #region Private methods private Rectangle CalculateItemRectangle(ListViewItem item, Rectangle boundRect) { Rectangle bounds = item.GetBounds(ItemBoundsPortion.Label); Rectangle rect = new Rectangle(boundRect.Left, bounds.Top, boundRect.Width, bounds.Height); int offset = CalculateOffset(item); rect.X += offset; rect.Width -= offset; return rect; } private int CalculateOffset( ListViewItem item ) { return 17 + (item.ListView.CheckBoxes ? 17 : 0); } /// /// Calculated content rectangle of Item /// private Rectangle CalculateContentRectangle( ListViewItem item, Graphics g, Rectangle rect ) { RichText.RichText text = (RichText.RichText)myItems[item]; IntPtr hdc = g.GetHdc(); try { Rectangle result = new Rectangle(rect.Location, text.GetSize(hdc).ToSize()); result.Width = rect.Width; return result; } finally { g.ReleaseHdc( hdc ); } } /// /// Draws dotted rectangle /// private void DrawDottedRectangle( Graphics g, Rectangle rect ) { Pen pen = new Pen(new HatchBrush(HatchStyle.Percent50, SystemColors.Highlight, Color.Black)); g.DrawRectangle(pen, rect); } #endregion } }