/*
* SimpleListView.cs - Simple list view control with icons and captions.
*
* Copyright (C) 2004 - 2011 Andreas Scherrer
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace Level9
{
///
/// Simple list view control with icons and captions.
///
public class SimpleListView : Panel
{
// -- Constants ------------------------------------------------------
///
/// The vertical spacing between list view items in pixels.
///
const int V_SPACING = 7;
///
/// The spacing between component border and icons in pixels.
///
const int BORDER_SPACING = 5;
///
/// The vertical spacing between icons and captions in pixels.
///
const int CAPTION_SPACING = 3;
// -- Attributes -----------------------------------------------------
///
/// A list of list view items.
///
List listViewItems =
new List();
///
/// The number of the currently selected item. A value of -1 means that
/// no item is selected.
///
int selected = -1;
// -- Events ---------------------------------------------------------
/// Occurs when a list view item has been clicked.
public event ListViewItemClickedEventHandler ItemClicked;
// -- Constructor ----------------------------------------------------
///
/// Initializes a new instance of the SimpleListView class.
///
public SimpleListView()
{
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
// -- Event handling -------------------------------------------------
///
/// Handles the MouseDown event.
///
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
int item = GetItemByPoint(new Point(e.X, e.Y));
if (item >= 0) {
int prevSelected = selected;
selected = item;
if (ItemClicked != null) {
ListViewItemClickedEventArgs args = new
ListViewItemClickedEventArgs(listViewItems[item]);
ItemClicked(this, args);
}
InvalidateItem(selected);
if (prevSelected >= 0) {
InvalidateItem(prevSelected);
}
}
}
///
/// Handles the Paint event.
///
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
SolidBrush fgBrush = new SolidBrush(this.ForeColor);
SolidBrush bgBrush = new SolidBrush(this.BackColor);
SolidBrush textBrush = null;
for (int i = 0; i < listViewItems.Count; i++) {
SimpleListViewItem item = listViewItems[i];
Rectangle rect = GetItemRect(i);
if (!rect.IntersectsWith(e.ClipRectangle)) {
continue;
}
//
// Draw background
//
if (i == selected) {
g.FillRectangle(SystemBrushes.ActiveCaption, rect);
textBrush = bgBrush;
}
else {
g.FillRectangle(bgBrush, rect);
textBrush = fgBrush;
}
//
// Draw image
//
int x = this.Width / 2 - item.Image.Width / 2
- SystemInformation.Border3DSize.Width;
int y = rect.Top + BORDER_SPACING;
g.DrawImage(item.Image, x, y, item.Image.Width,
item.Image.Height);
//
// Draw caption
//
x = this.Width / 2 - GetCaptionWidth(item.Text) / 2
- SystemInformation.Border3DSize.Width;
y = rect.Top + BORDER_SPACING + item.Image.Height
+ CAPTION_SPACING;
g.DrawString(item.Text, this.Font, textBrush, x, y);
}
fgBrush.Dispose();
bgBrush.Dispose();
}
// -- Methods --------------------------------------------------------
///
/// Adds an item to the list view.
///
/// a list view item
public void AddListViewItem(SimpleListViewItem listViewItem)
{
if (listViewItem != null && listViewItem.Image != null) {
listViewItems.Add(listViewItem);
}
}
///
/// Sets the selected list view item.
///
/// the selected list view item
public void SetSelectedItem(SimpleListViewItem listViewItem)
{
if (listViewItem == null) {
return;
}
for (int i = 0; i < listViewItems.Count; i++) {
if (listViewItem != listViewItems[i]) {
continue;
}
selected = i;
if (ItemClicked != null) {
ListViewItemClickedEventArgs args = new
ListViewItemClickedEventArgs(listViewItems[i]);
ItemClicked(this, args);
}
this.Invalidate();
break;
}
}
///
/// Invalidates a list view item that must be redrawn.
///
/// a list view item
void InvalidateItem(int item)
{
this.Invalidate(GetItemRect(item));
}
///
/// Provides the list view item that's associated with a given point
/// on the component.
///
/// a point on the component
/// the list view item number
int GetItemByPoint(Point point)
{
for (int i = 0; i < listViewItems.Count; i++) {
Rectangle itemRect = GetItemRect(i);
if (itemRect.Contains(point)) {
return i;
}
}
return -1;
}
///
/// Provides the rectangle that's associated with a list view item.
///
/// the list view item number
/// a rectangle
Rectangle GetItemRect(int item)
{
SimpleListViewItem listViewItem = null;
int yOffset = V_SPACING;
for (int i = 0; i < item; i++) {
listViewItem = listViewItems[i];
yOffset += V_SPACING + BORDER_SPACING * 2
+ listViewItem.Image.Height + CAPTION_SPACING
+ this.Font.Height;
}
listViewItem = listViewItems[item];
int height = listViewItem.Image.Height + CAPTION_SPACING
+ this.Font.Height + BORDER_SPACING * 2;
int width = Math.Max(GetCaptionWidth(listViewItem.Text),
listViewItem.Image.Width) + BORDER_SPACING * 2
- SystemInformation.Border3DSize.Width;
int xOffset = this.Width / 2 - width / 2 - 2;
return new Rectangle(xOffset, yOffset, width, height);
}
///
/// Provides the width of a list view item's caption.
///
/// the caption
/// the caption width
int GetCaptionWidth(string caption)
{
Graphics g = this.CreateGraphics();
SizeF width = g.MeasureString(caption, this.Font);
g.Dispose();
return (int)Math.Ceiling(width.Width);
}
}
///
/// Represents the method that handles a ListViewItemClicked event.
///
public delegate void ListViewItemClickedEventHandler(Object sender,
ListViewItemClickedEventArgs e);
///
/// Provides data for the ListViewItemClicked event.
///
public class ListViewItemClickedEventArgs : EventArgs
{
// -- Attributes -----------------------------------------------------
///
/// The list view item.
///
SimpleListViewItem item = null;
// -- Constructors ---------------------------------------------------
///
/// Initializes a new instance of the ListViewItemClickedEventArgs
/// class.
///
/// the list view item
public ListViewItemClickedEventArgs(SimpleListViewItem item)
{
this.item = item;
}
// -- Accessors ------------------------------------------------------
///
/// Gets or sets the list view item.
///
public SimpleListViewItem Item
{
get {
return item;
}
set {
item = value;
}
}
}
///
/// Represents a simple list view item.
///
public class SimpleListViewItem
{
// -- Attributes -----------------------------------------------------
///
/// The list view item's image.
///
Image image = null;
///
/// The text of the list view item's caption.
///
string text = null;
// -- Constructor ----------------------------------------------------
///
/// Initializes a new instance of the SimpleListViewItem class.
///
/// the list view item's image
/// the text of the list view item's caption
public SimpleListViewItem(Image image, string text)
{
this.image = image;
this.text = text;
}
// -- Accessors ------------------------------------------------------
///
/// Gets or sets the list view item's image.
///
public Image Image
{
get {
return this.image;
}
set {
this.image = value;
}
}
///
/// Gets or sets the text of the list view item's caption.
///
public string Text
{
get {
return this.text;
}
set {
this.text = value;
}
}
}
}