///
/// 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.Drawing;
using System.Windows.Forms;
using JetBrains.UI.Interop;
namespace JetBrains.UI.Components.CustomListBox
{
public delegate void WindowsEventHandler( object sender, ref Message m );
///
/// Summary description for CustomListBox.
///
public class CustomListBox : System.Windows.Forms.ListBox
{
///
/// The item painter to use
///
private IItemPainter myItemPainter;
private int mySelectedIndexPreview;
public event WindowsEventHandler MouseEvent;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
public CustomListBox()
{
mySelectedIndexPreview = SelectedIndex;
DrawMode = DrawMode.OwnerDrawVariable;
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
}
public IItemPainter ItemPainter
{
get { return myItemPainter; }
set { myItemPainter = value; }
}
public static Color SelectionBackColor(bool isFocused)
{
Color result = SystemColors.Highlight;
if ( !isFocused )
result = Color.FromArgb(result.A/2,result);
return result;
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
//
// CustomListBox
//
this.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
}
#endregion
// private Rectangle GetFullItemRectangle(int index)
// {
// //TODO: GetItemRectangle works strange
// Rectangle rectangle = GetItemRectangle(index);
// rectangle.Height = GetItemHeight(index) + 1;
// return rectangle;
// }
// protected override void OnSelectedIndexChanged(EventArgs e)
// {
// try
// {
// SuspendLayout();
// if (myOldSelectedIndex != SelectedIndex)
// {
// if ( myOldSelectedIndex >= 0 && myOldSelectedIndex < Items.Count )
// Invalidate(GetFullItemRectangle(myOldSelectedIndex));
// int index = SelectedIndex;
// if ( index >= 0 && index < Items.Count )
// Invalidate(GetFullItemRectangle(index));
// myOldSelectedIndex = SelectedIndex;
// }
// base.OnSelectedIndexChanged (e);
// ResumeLayout(false);
// }
// catch (Exception ex)
// {
// System.Console.Write( ex );
// }
// }
//
//
protected override void OnDrawItem(DrawItemEventArgs e)
{
try
{
if ( myItemPainter != null && e.Index >= 0 && e.Index < Items.Count )
{
//System.Console.WriteLine(e.Bounds.Height);
myItemPainter.Draw(Items[e.Index], e.Graphics, e.Bounds, e.Index == mySelectedIndexPreview);
}
else
{
base.OnDrawItem(e);
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine("CustomListBox.DrawItem failed : " + ex, "UI");
Invalidate(e.Bounds);
}
}
protected override void OnMeasureItem(MeasureItemEventArgs e)
{
try
{
if (myItemPainter != null)
{
Size size = myItemPainter.GetSize(Items[e.Index], e.Graphics);
e.ItemWidth = size.Width;
e.ItemHeight = size.Height;
}
else
{
base.OnMeasureItem(e);
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine("CustomListBox.MeasureItem failed : " + ex, "UI");
}
}
private void CheckSelectedIndexPreview(int index)
{
if ( index != mySelectedIndexPreview )
{
if ( mySelectedIndexPreview != -1 && mySelectedIndexPreview < Items.Count )
Invalidate(GetItemRectangle(mySelectedIndexPreview));
mySelectedIndexPreview = index;
}
}
public override int SelectedIndex
{
get
{
return base.SelectedIndex;
}
set
{
//System.Console.WriteLine("Old index=" + SelectedIndex + ", new index=" + value);
CheckSelectedIndexPreview(value);
if ( SelectedIndex != -1 )
{
Rectangle rectangle = GetItemRectangle(SelectedIndex);
rectangle.Height+=2;//TODO: remove +2
Invalidate(rectangle);
}
base.SelectedIndex = value;
}
}
protected override void OnSelectedIndexChanged (EventArgs e)
{
CheckSelectedIndexPreview(SelectedIndex);
base.OnSelectedIndexChanged (e);
}
protected override void CreateHandle ()
{
//TODO: a hack to be able to close the box with double click
if (!IsDisposed)
base.CreateHandle ();
}
protected override void WndProc(ref Message m)
{
if ((m.Msg >= Win32Declarations.WM_MOUSEFIRST && m.Msg <= Win32Declarations.WM_MOUSELAST) ||
(m.Msg >= Win32Declarations.WM_NCMOUSEFIRST && m.Msg <= Win32Declarations.WM_NCMOUSELAST))
if (MouseEvent != null)
MouseEvent(this, ref m);
if (m.Msg == Win32Declarations.WM_ERASEBKGND)
return;
base.WndProc (ref m);
}
}
}