///
/// 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.Drawing;
using System.Windows.Forms;
using JetBrains.DataStructures;
namespace JetBrains.JetListViewLibrary
{
public enum CheckBoxState
{
Hidden, Unchecked, Checked, Grayed
}
public class CheckBoxEventArgs
{
private readonly object _item;
private readonly CheckBoxState _oldState;
private CheckBoxState _newState;
public CheckBoxEventArgs( object item, CheckBoxState oldState, CheckBoxState newState )
{
_item = item;
_oldState = oldState;
_newState = newState;
}
public object Item
{
get { return _item; }
}
public CheckBoxState OldState
{
get { return _oldState; }
}
public CheckBoxState NewState
{
get { return _newState; }
set { _newState = value; }
}
}
public delegate void CheckBoxEventHandler( object sender, CheckBoxEventArgs e );
///
/// A column in JetListView which supports drawing checkboxes.
///
public class CheckBoxColumn: JetListViewColumn
{
private readonly HashMap _checkStates = new HashMap();
private JetListViewNode _mouseDownNode;
public event CheckBoxEventHandler BeforeCheck;
public event CheckBoxEventHandler AfterCheck;
public CheckBoxColumn()
{
Width = 18;
FixedSize = true;
_showHeader = false;
}
protected internal override void DrawItem( Graphics g, Rectangle rc, object item,
RowState state, string highlightText )
{
int midPoint = (rc.Left + rc.Right) / 2;
Rectangle rcCheck = new Rectangle( midPoint - 7, rc.Top, 15, 15 );
CheckBoxState checkState = GetItemCheckState( item );
if ( checkState != CheckBoxState.Hidden )
{
ButtonState buttonState;
switch( checkState )
{
case CheckBoxState.Checked: buttonState = ButtonState.Checked; break;
case CheckBoxState.Grayed: buttonState = ButtonState.Inactive; break;
default: buttonState = ButtonState.Normal; break;
}
if ( ( state & RowState.Disabled ) != 0 )
{
buttonState |= ButtonState.Inactive;
}
OwnerControl.ControlPainter.DrawCheckBox( g, rcCheck, buttonState );
}
}
protected internal override MouseHandleResult HandleMouseDown( JetListViewNode node, int x, int y )
{
_mouseDownNode = node;
if ( x >= 0 && x < Width )
{
return MouseHandleResult.Handled;
}
return 0;
}
protected internal override bool HandleMouseUp( JetListViewNode node, int x, int y )
{
base.HandleMouseUp( node, x, y );
bool toggleCheck = (_mouseDownNode == node);
_mouseDownNode = null;
if ( toggleCheck )
{
ToggleCheckState( node.Data );
}
return x >= 0 && x < Width;
}
protected internal override bool HandleKeyDown( JetListViewNode node, KeyEventArgs e )
{
if ( e.KeyData == Keys.Space )
{
ToggleSelectionCheckState( node.Data );
return true;
}
return false;
}
private void ToggleSelectionCheckState( object item )
{
if ( OwnerControl.Selection.Contains( item ) )
{
CheckBoxState oldCheckState = GetItemCheckState( item );
if ( oldCheckState != CheckBoxState.Hidden && oldCheckState != CheckBoxState.Grayed )
{
CheckBoxState newCheckState = ( oldCheckState == CheckBoxState.Checked )
? CheckBoxState.Unchecked
: CheckBoxState.Checked;
foreach( object selItem in OwnerControl.Selection )
{
SetItemCheckState( selItem, newCheckState );
}
}
}
else
{
ToggleCheckState( item );
}
}
private void ToggleCheckState( object item )
{
CheckBoxState oldCheckState = GetItemCheckState( item );
if ( oldCheckState != CheckBoxState.Hidden && oldCheckState != CheckBoxState.Grayed )
{
CheckBoxState newCheckState = ( oldCheckState == CheckBoxState.Checked )
? CheckBoxState.Unchecked
: CheckBoxState.Checked;
SetItemCheckState( item, newCheckState );
}
}
public void SetItemCheckState( object item, CheckBoxState newCheckState )
{
CheckBoxEventArgs args = new CheckBoxEventArgs( item, GetItemCheckState( item ), newCheckState );
if ( BeforeCheck != null )
{
BeforeCheck( this, args );
}
_checkStates [item] = args.NewState;
if ( args.OldState != args.NewState )
{
OnAfterCheck( args );
OwnerControl.InvalidateItem( item );
}
}
protected virtual void OnAfterCheck( CheckBoxEventArgs args )
{
if ( AfterCheck != null )
{
AfterCheck( this, args );
}
}
public CheckBoxState GetItemCheckState( object item )
{
if ( !_checkStates.Contains( item ) )
{
return GetDefaultCheckState( item );
}
return (CheckBoxState) _checkStates [item];
}
protected virtual CheckBoxState GetDefaultCheckState( object item )
{
return CheckBoxState.Unchecked;
}
public override string GetToolTip( JetListViewNode node, Rectangle rc, ref bool needPlace )
{
return null;
}
protected internal override int GetWidthDelta( JetListViewNode node )
{
if ( GetItemCheckState( node.Data ) == CheckBoxState.Hidden )
{
return -Width;
}
return base.GetWidthDelta( node );
}
}
}